
var resultStr="";
var resultTypeRecord=[];// 1:原始字串; 2:引用 用于判断什么时候该用"0"分隔

/**
 * 初始化, 以防止上一次运行的结果叠加
 */
function init()
{
  resultStr="";
  resultTypeRecord=[];
}

/**
 * 插入原始字串
 */
function insertResultOriginStr(str)
{
  if(resultTypeRecord.length)
  {
    if(1 == resultTypeRecord[resultTypeRecord.length-1])
    {
      resultStr+= "0";
    }
  }
  resultStr+=str.length;
  resultStr+=str;
  resultTypeRecord.push(1);
}

/**
 * 插入引用
 */
function insertResultRefStr(length,numberInPrevStr)
{
  if(resultTypeRecord.length)
  {
    if(2 == resultTypeRecord[resultTypeRecord.length-1])
    {
      resultStr+= "0";
    }
  }
  resultStr+=length;
  resultStr+=numberInPrevStr;
  resultTypeRecord.push(2);
}

/**
 * 解决方案
 */
function solution(input,ns)
{
  // 分析字串
  var length = input.length;
  ns.tprint("字符长度:",length , "  数据源:", input);
  
  // 取第一个串
  var prevStr="";
  var firstTime = true;// 第一次没被重复的情况, 一但被重复, 前一串就不能自增长了
  var nextOriginStr="";// 下一个原始串, 原始串可能有多个. 
  for(let i=0;i<length;++i)
  {
    var currentCharacter = input[i];
    if(!firstTime)
    {
      if(9==nextOriginStr.length)
      {
        insertResultOriginStr(nextOriginStr);
        nextOriginStr = "";
      }
      nextOriginStr+=currentCharacter;
      ns.tprint("i:",i,"\t nextOriginStr:",nextOriginStr ,"\t prevStr:",prevStr,"\t结果串:",resultStr);
    }
    // 是否在第一串中的重复?
    let posInPreview = prevStr.indexOf(currentCharacter);
    if(-1!=posInPreview)
    {
      // 有一个字符匹配, 可能有之后的其它字符在之前的串匹配
      var nextSubStr = ""+currentCharacter;
      ns.tprint("j:",1,"\t length-i:",length-i,"\ti+j:",i+1 ,"\tcurrentCharacter:",currentCharacter,"\ti:",i);
      for(let j=1;j<length-i;++j)
      {
        let character2 = input[i+j];
        nextSubStr+=character2;
        ns.tprint("匹配中的子串(两个字符):",nextSubStr);
        let posInPreview = prevStr.indexOf(nextSubStr);
        if(-1 ==posInPreview)
        {
          // 子串重复不只一次的话, 就会涉及多个字符, 在这判断不合适
          nextSubStr=nextSubStr.substring(0,nextSubStr.length-1);
          break;
        }
        else
        {
          // 继续找子串
        }
      }// END for
      // 判断后来的子串的最后一字, 以之前子串的最后一字相同
      if(nextSubStr[nextSubStr.length-1] == prevStr[prevStr.length-1])
      {
        ns.tprint(" 匹配的子串:",nextSubStr);
        if(1==nextSubStr.length)
        {
          ns.tprint("子串太短该被丢弃");// 这样的话, 不兼容aaaaaaaa这一大串
          // 是不是上一串的倒数几个字
          if(prevStr.length-1 == nextSubStr)
          {
            ns.tprint("   上一串的最后一个字符重复");
          }
          else
          {
            ns.tprint("   不在上一串的最后一个字");// 兼容aaaaaaaa这一大串
          }
          prevStr+=(currentCharacter);
        }
        else
        {
          if(firstTime)
          {
            // 前一串该换了.
            ns.tprint("前一串该换了,提交之前的字串:",prevStr);
          }
          //posInPreview = "";
          var posSbuStr = prevStr.indexOf(nextSubStr);
          var refInPrevStr = prevStr.length- posSbuStr;
          
          // 判断是子串重复的情况:
          if(nextSubStr[0]==input[i+nextSubStr.length])
          {
            ns.tprint("子串重复");
            var subStr2="";// 重复的串
            var lengthOfSubStr = nextSubStr.length;// 用于取模, 计算重复了几次
            var baseNumber = i+nextSubStr.length;// 基准, 用于取模, 再与nextSubStr[?]比对
            for(let j=baseNumber;j<length;++j)
            {
              var currentMirrorIndex = (j-baseNumber)%lengthOfSubStr;
              ns.tprint("\t\t currentMirrorIndex:",currentMirrorIndex,"\t j:",j);
              ns.tprint("\t\t input[j]:",input[j],"\t nextSubStr[currentMirrorIndex]:",nextSubStr[currentMirrorIndex]);
              if(input[j]==nextSubStr[currentMirrorIndex])
              {
                subStr2+=input[j];
              }
              else
              {
                break;
              }
            }// END for
            nextSubStr+=subStr2;
            ns.tprint("子串重复的新的串:",nextSubStr);
          }
          ns.tprint("匹配的长度:",nextSubStr.length," 从上一串的倒数第几个开始:",refInPrevStr);
          if(9<nextSubStr.length)
          {
            ns.tprint("子串过长:",nextSubStr,"\t长度:",nextSubStr.length)
          }
          if(firstTime)
          {
            insertResultOriginStr(prevStr);
          }
          else if(nextOriginStr.length>1)
          {
            nextOriginStr=nextOriginStr.substring(0,nextOriginStr.length-1);
            insertResultOriginStr(nextOriginStr);// 之后nextOriginStr会置空
          }
          // 计算下一个"前一串"
          prevStr += nextSubStr;
          if(prevStr.length>9)
          {
            prevStr=prevStr.substring(prevStr.length-9);
            //前面的串太长,进行裁剪
            ns.tprint("前面的串太长,进行裁剪:",prevStr);
          }
          firstTime = false;// 前一串不能再自增长
          ns.tprint("原本的下标:",i);
          // 往下计算, 这一串就这么定了
          i+=nextSubStr.length-1;// 这里的-1是因为for循环会自增+1
          ns.tprint("跨过子串后的下标:",i);
          nextOriginStr = "";// 现在正在计算的是有镜像的串, 不会有下一个原始串.
          // 记录这个重复的串:
          insertResultRefStr(nextSubStr.length,refInPrevStr);
          // 当前串不是原始串, 所以原始串另行计算
        }// nextSubStr 不只一个字符的else情况
      }// END if 判断后来的子串的最后一字, 以之前子串的最后一字相同
      else
      {
        prevStr+=currentCharacter;
        if(prevStr.length>9)
        {
          //ns.tprint("####    该提前存一下目前的串,不然太长",prevStr,"\t长:",prevStr.length);
          prevStr=prevStr.substring(prevStr.length-9);
          //前面的串太长,进行裁剪
          ns.tprint("前面的串太长,进行裁剪:",prevStr);
        }
      }
    }
    else
    {
      // 由于上面一段会因匹配的串跳过一段,所以这里对prevStr的修改不能移动到if-else之外
      //if(firstTime)
      {
        prevStr+=currentCharacter;
        if(prevStr.length>9)
        {
          //ns.tprint("####    该提前存一下目前的串,不然太长",prevStr,"\t长:",prevStr.length);
          prevStr=prevStr.substring(prevStr.length-9);
          //前面的串太长,进行裁剪
          ns.tprint("前面的串太长,进行裁剪:",prevStr);
        }
      }
    }
  }// END for
  if(nextOriginStr.length)
  {
    insertResultOriginStr(nextOriginStr);
  }
  ns.tprint("最终结果:",resultStr);
  ns.tprint("-----------");
}// END solution 

/** 主函数 */
export async function main(ns) {
  init();
  // 输入串
  var input1 = "abracadabra";
  solution(input1,ns);
  
  init();
  // 第二个例子就有把原始串重复几次的做法, 而且重复的是原始串的子串, 并不是原始串重复.
  var input2 = "mississippi";
  solution(input2,ns);

  // aAAaAAaAaAA -> 3aAA53035
  init();
  var input3 = "aAAaAAaAaAA";
  solution(input3,ns);

  // 2718281828 -> 627182844
  init();
  var input4 = "2718281828";
  solution(input4,ns);

  //aaaaaaaaaaaa -> 3aaa91
  init();
  var input5 = "aaaaaaaaaaaa";
  solution(input5,ns);
  
  // VIXio57k57kk57kk6YJBxivhVLc1lYVYsVYsV306c5cDcQ6j6cQ6j6cQzzzzzzzzzPPvwMA6MA6V5wMfbOEXEXEXEXEXq
  init();
  var input6 = "VIXio57k57kk57kk6YJBxivhVLc1lYVYsVYsV306c5cDcQ6j6cQ6j6cQzzzzzzzzzPPvwMA6MA6V5wMfbOEXEXEXEXEXq";
  solution(input6,ns);
}
